/**
 * 
 */
package com.google.code.cisx.client.gadgets;

import com.google.code.cisx.client.model.Gadget;
import com.google.code.cisx.client.model.GadgetClass;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.widgetideas.table.client.FixedWidthFlexTable;
import com.google.gwt.widgetideas.table.client.FixedWidthGrid;
import com.google.gwt.widgetideas.table.client.ListCellEditor;
import com.google.gwt.widgetideas.table.client.PagingScrollTable;
import com.google.gwt.widgetideas.table.client.RadioCellEditor;
import com.google.gwt.widgetideas.table.client.ScrollTable;
import com.google.gwt.widgetideas.table.client.TableBulkRenderer;
import com.google.gwt.widgetideas.table.client.TextCellEditor;
import com.google.gwt.widgetideas.table.client.PagingScrollTable.CellRenderer;
import com.google.gwt.widgetideas.table.client.overrides.Grid;
import com.google.gwt.widgetideas.table.client.overrides.HTMLTable;
import com.google.gwt.widgetideas.table.client.overrides.FlexTable.FlexCellFormatter;

/**
 * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
 * @since 1.0
 * @version $Id: CommonListGadget.java 161 2008-02-02 05:52:28Z
 *          rahul.thakur.xdev $
 */
public class CommonListGadget extends Gadget implements GadgetEventListener<GadgetEvent> {

  public static class Class extends GadgetClass {
    public Class() {
      this("CommonList", true, true /* secured */);
    }

    /**
     * @param n
     * @param r
     */
    private Class(String n, boolean r) {
      super(n, r);
    }

    /**
     * @param name
     * @param refreshable
     * @param secured
     */
    private Class(String name, boolean refreshable, boolean secured) {
      super(name, refreshable, secured);     
    }

    @Override
    public Gadget newGadget() {
      return new CommonListGadget(this);
    }

  }

  /**
   * PagingScrollTable
   */
  /**
   * A custom cell renderer.
   */
  private static class CustomBulkRenderer extends TableBulkRenderer.CellRenderer {
    @Override
    public void renderCell(int row, int column, Object cellData, StringBuffer accum) {
      if (cellData == null) {
        return;
      }

      switch (column) {
        case 5:
          accum.append("<FONT color=\"" + cellData + "\">" + cellData + "</FONT>");
          return;
        default:
          accum.append(cellData.toString());
      }
    }
  }

  /**
   * A custom cell renderer.
   */
  private static class CustomCellRenderer implements CellRenderer {

        public void renderCell( FixedWidthGrid grid, int row, int column, Object data ) {
            if ( data == null ) {
                grid.clearCell( row, column );
            }

            switch ( column ) {
                case 0:
                    grid.setWidget( row, column, (Widget) data );
                    break;
                case 5:
                    grid.setHTML( row, column, "<FONT color=\"" + data + "\">" + data + "</FONT>" );
                    break;
                default:
                    grid.setHTML( row, column, data + "" );
            }
        }

    }

  /**
   * The data portion of the {@link ScrollTable}.
   */
  protected static FixedWidthGrid dataTable = null;

  /**
   * The footer portion of the {@link ScrollTable} .
   */
  protected static FixedWidthGrid footerTable = null;

  /**
   * The header portion of the {@link ScrollTable}.
   */
  protected static FixedWidthFlexTable headerTable = null;

  /**
   * The scroll table.
   */
  protected static ScrollTable scrollTable = null;

  /**
   * The {@link CachedTableController} used in the {@link PagingScrollTable}.
   */
  //protected static CachedTableController tableController = null;

  /**
   * The {@link DataSourceTableModel}.
   */
  //protected static DataSourceTableModel tableModel = null;

  /**
   * Get the data table.
   * 
   * @return the data table.
   */
  public static FixedWidthGrid getDataTable() {
    if (dataTable == null) {
      dataTable = new FixedWidthGrid();
      //dataTable.setHoveringPolicy(SelectionGrid.HOVERING_POLICY_ROW);      
    }
    return dataTable;
  }

  /**
   * Get the data table.
   * 
   * @return the data table.
   */
  public static FixedWidthGrid getEditableGridView() {
    //return (EditablePagingGrid) dataTable;
    return dataTable;
  }

  /**
   * Get the footer table.
   * 
   * @return the footer table.
   */
  public static FixedWidthGrid getFooterTable() {
    if (footerTable == null) {
      footerTable = new FixedWidthGrid();
    }
    return footerTable;
  }

  /**
   * Get the header table.
   * 
   * @return the header table.
   */
  public static FixedWidthFlexTable getHeaderTable() {
    if (headerTable == null) {
      headerTable = new FixedWidthFlexTable();
    }
    return headerTable;
  }

  /**
   * Get the scroll table.
   * 
   * @return the scroll table.
   */
  public static PagingScrollTable getPagingScrollTable() {
    return (PagingScrollTable) scrollTable;
  }

  /**
   * Get the scroll table.
   * 
   * @return the scroll table.
   */
  public static ScrollTable getScrollTable() {
    return scrollTable;
  }

  /**
   * Get the table controller.
   * 
   * @return the table controller
   */
 // public static CachedTableController getTableController() {
  //  return tableController;
  //}

  /**
   * Get the table model.
   * 
   * @return the table model
   */
 // public static DataSourceTableModel getTableModel() {
  //  return tableModel;
  //}

  /**
   * @param gc
   */
  private CommonListGadget(GadgetClass gc) {
    super(gc);
    // Create the inner tables
    getHeaderTable();
    getFooterTable();

    // Setup the controller
   // tableModel = createDataSourceTableModel(); // TODO: Extract to template method
    /*
    tableController = createCacheTableController(); // TODO: Extract to template method
    tableController.setNumRows(10000);
    tableController.setNumPreCachedRows(20);
    tableController.setNumPostCachedRows(20);

    // Setup the view
    EditablePagingGrid gridView = new EditablePagingGrid(tableController);
    dataTable = gridView;
    gridView.setCellRenderer(new CustomCellRenderer()); // TODO: Extract to template method
    setupCellEditors(gridView);

    // Setup the renderer
    PagingGridBulkRenderer dataRenderer = new PagingGridBulkRenderer(gridView, 12);
    dataRenderer.setCellRenderer(new CustomBulkRenderer());

    // Create the scroll table
    scrollTable = new PagingScrollTable(gridView, headerTable);
    getPagingScrollTable().setPageSize(10);    
    scrollTable.setFooterTable(getFooterTable());

    // Add some data to the footer table
    footerTable.resize(1, 12);
    for (int i = 0; i < 12; i++) {
      footerTable.setText(0, i, "Col " + i);
    }
    scrollTable.setFooterTable(footerTable);
     */

    // Setup the scroll table
    setupScrollTable();

    // Add the table to the page
    VerticalPanel mainPanel = new VerticalPanel();
    initWidget(mainPanel);
    mainPanel.setWidth("100%");
    TabPanel tabPanel = createTabPanel();
    mainPanel.add(scrollTable);
    mainPanel.add(tabPanel);
  }

  /**
   * @return
   */
 // private DataSourceTableModel createDataSourceTableModel() {
  //  return new DataSourceTableModel();
 // }

  /**
   * Create a new tab panel with options to affect the grid.
   * 
   * @return the new tab panel
   */
  private TabPanel createTabPanel() {
    TabPanel panel = new TabPanel();
    panel.setWidth("95%");

    // Add the panels
    // panel.add(new DemoTabResizing(), "Resizability");
    // panel.add(new DemoTabColumnWidth(), "Column Width");
    // panel.add(new DemoTabHighlighting(), "Highlighting");
    // panel.add(new DemoTabSorting(), "Sorting");
    // panel.add(new DemoTabHeaderManipulation(), "Header Manipulation");
    // panel.add(new ModeledTabDataManipulation(), "Data Manipulation");
    // panel.add(new ModeledTabPaging(), "Paging");
    // panel.add(new DemoTabPanelLog(), "Log");
    // panel.selectTab(0);

    // Return the new panel
    return panel;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.google.code.cisx.client.event.TypedEventListener#onEvent(com.google.code.cisx.client.event.TypedEvent)
   */
  public void onEvent(GadgetEvent event) {
    // TODO Auto-generated method stub

  }

  /**
   * Setup the cell editors on the scroll table.
   */
  private void setupCellEditors(FixedWidthGrid gridView) {
    // Integer only cell editor for age
    TextBox intOnlyTextBox = new TextBox();
    intOnlyTextBox.setWidth("4em");
    intOnlyTextBox.addKeyboardListener(new KeyboardListenerAdapter() {
      @Override
    public void onKeyPress(Widget sender, char keyCode, int modifiers) {
        if ((!Character.isDigit(keyCode)) && (keyCode != (char) KEY_TAB)
            && (keyCode != (char) KEY_BACKSPACE) && (keyCode != (char) KEY_DELETE)
            && (keyCode != (char) KEY_ENTER) && (keyCode != (char) KEY_HOME)
            && (keyCode != (char) KEY_END) && (keyCode != (char) KEY_LEFT)
            && (keyCode != (char) KEY_UP) && (keyCode != (char) KEY_RIGHT)
            && (keyCode != (char) KEY_DOWN)) {
          ((TextBox) sender).cancelKey();
        }
      }
    });
    //gridView.setCellEditor(2, new TextCellEditor(intOnlyTextBox));

    // Gender cell editor
    RadioCellEditor genderEditor = new RadioCellEditor();
    genderEditor.setLabel("Select a gender:");
    //genderEditor.addOption("male");
    //genderEditor.addOption("female");
    //gridView.setCellEditor(3, genderEditor);

    // Race cell editor
    ListCellEditor raceEditor = new ListCellEditor();
    ListBox raceBox = raceEditor.getListBox();
    for (int i = 0; i < DataSourceData.races.length; i++) {
      raceBox.addItem(DataSourceData.races[i]);
    }
//    gridView.setCellEditor(4, raceEditor);

    // Color cell editor
    RadioCellEditor colorEditor = new RadioCellEditor() {
      protected Object getCellValue(HTMLTable table, int row, int cell) {
        return table.getText(row, cell);
      }
    };
    colorEditor.setLabel("Select a color:");
    for (int i = 0; i < DataSourceData.colors.length; i++) {
//      colorEditor.addOption(DataSourceData.colors[i]);
    }
//    gridView.setCellEditor(5, colorEditor);

    // Sport cell editor
    ListCellEditor sportEditor = new ListCellEditor();
    sportEditor.setLabel("Select a sport:");
    ListBox sportBox = sportEditor.getListBox();
    for (int i = 0; i < DataSourceData.sports.length; i++) {
      sportBox.addItem(DataSourceData.sports[i]);
    }
//    gridView.setCellEditor(6, sportEditor);

    // College cell editor
    TextCellEditor collegeEditor = new TextCellEditor() {
      protected Object getCellValue(HTMLTable table, int row, int cell) {
        return table.getText(row, cell).substring(14);
      }

      @Override
    public Object getValue() {
        Object value = super.getValue();
        return "University of " + value;
      }

      public boolean onAccept(Object value) {
        if (super.getValue().equals("")) {
          Window.alert("You must enter a school");
          return false;
        }
        return true;
      }
    };
    collegeEditor.setLabel("University of");
//    gridView.setCellEditor(7, collegeEditor);
  }

  /**
   * Setup the scroll table.
   */
  private void setupScrollTable() {
    // Setup the formatting
    scrollTable.setCellPadding(3);
    scrollTable.setCellSpacing(0);
    scrollTable.setSize("95%", "50%");
//    scrollTable.setResizePolicy(ScrollTable.RESIZE_POLICY_FILL_WIDTH);

    // Set column widths
    scrollTable.setColumnWidth(1, 100);
    scrollTable.setColumnWidth(2, 35);
    scrollTable.setColumnWidth(3, 45);
    scrollTable.setColumnWidth(4, 110);
    scrollTable.setColumnWidth(5, 80);
    scrollTable.setColumnWidth(6, 110);
    scrollTable.setColumnWidth(7, 180);
    scrollTable.setColumnWidth(8, 35);
    scrollTable.setColumnWidth(9, 35);
    scrollTable.setColumnWidth(10, 55);
    scrollTable.setColumnWidth(11, 45);

    // Level 1 headers
    FlexCellFormatter headerFormatter = headerTable.getFlexCellFormatter();
    headerTable.setHTML(0, 0, "User Information");
    headerFormatter.setColSpan(0, 0, 12);

    // Level 2 headers
    headerTable.setHTML(1, 0, "First and Last Name");
    headerFormatter.setColSpan(1, 0, 2);
    headerFormatter.setRowSpan(1, 0, 2);
    headerTable.setHTML(1, 1, "General Info");
    headerFormatter.setColSpan(1, 1, 3);
    headerTable.setHTML(1, 2, "Favorite Color");
    headerFormatter.setColSpan(1, 2, 1);
    headerFormatter.setRowSpan(1, 2, 2);
    headerTable.setHTML(1, 3, "Preferred Sport");
    headerFormatter.setColSpan(1, 3, 1);
    headerFormatter.setRowSpan(1, 3, 2);
    headerTable.setHTML(1, 4, "School Info");
    headerFormatter.setColSpan(1, 4, 3);
    headerTable.setHTML(1, 5, "Login Info");
    headerFormatter.setColSpan(1, 5, 2);

    // Level 3 headers
    headerTable.setHTML(2, 0, "Age");
    headerTable.setHTML(2, 1, "Gender");
    headerTable.setHTML(2, 2, "Race");
    headerTable.setHTML(2, 3, "College");
    headerTable.setHTML(2, 4, "Year");
    headerTable.setHTML(2, 5, "GPA");
    headerTable.setHTML(2, 6, "ID");
    headerTable.setHTML(2, 7, "Pin");
  }

}
